﻿using System.Diagnostics;
using System.Reflection;
using System.Text;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using MyCalManager.Helper;

namespace MyCalManager.ViewModel
{
    
    public class AboutViewModel : ViewModelBase
    {

        private const string propertyNameTitle = "Title";
        private const string propertyNameDescription = "Description";
        private const string propertyNameProduct = "Product";
        private const string propertyNameCopyright = "Copyright";
        private const string propertyNameCompany = "Company";
        private const string xPathRoot = "ApplicationInfo/";
        private const string xPathTitle = xPathRoot + propertyNameTitle;
        private const string xPathVersion = xPathRoot + "Version";
        private const string xPathDescription = xPathRoot + propertyNameDescription;
        private const string xPathProduct = xPathRoot + propertyNameProduct;
        private const string xPathCopyright = xPathRoot + propertyNameCopyright;
        private const string xPathCompany = xPathRoot + propertyNameCompany;
        private const string xPathLink = xPathRoot + "Link";
        private const string xPathLinkUri = xPathRoot + "Link/@Uri";

        public AboutViewModel()
        {
            Initialize();
        }

        private void Initialize()
        {
            this.Back = new RelayCommand(
                () => OnOk());

            this.GNU = new RelayCommand(
                () => Process.Start("http://www.gnu.org/licenses/"));

            this.Kaloma = new RelayCommand(
                () => Process.Start("http://www.kaloma.de/"));
        }



        private string GetText()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("Manage your Daily Calories");
            sb.AppendLine();
            sb.AppendLine();
            sb.Append("Many Thanks to Frank Böpple for his Foodstuff Database. See Kaloma Site.");
            sb.AppendLine();
            sb.AppendLine();
            sb.Append(@"This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, see GNU Licences.");
            sb.AppendLine();
            sb.AppendLine();
            sb.Append(@"Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU General Public License, wie von der Free Software Foundation veröffentlicht, weitergeben und/oder modifizieren, entweder gemäß Version 3 der Lizenz oder (nach Ihrer Option) jeder späteren Version. Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, daß es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem Programm erhalten haben. Falls nicht, siehe GNU Licences.");

            return sb.ToString();
        }

        #region Propertys

        private string CalculatePropertyValue<T>(string propertyName, string xpathQuery)
        {
            string result = string.Empty;
            // first, try to get the property value from an attribute.
            object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(T), false);
            if (attributes.Length > 0)
            {
                T attrib = (T)attributes[0];
                PropertyInfo property = attrib.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
                if (property != null)
                {
                    result = property.GetValue(attributes[0], null) as string;
                }
            }

            return result;
        }


        public string ProductTitle
        {
            get
            {
                string result = CalculatePropertyValue<AssemblyTitleAttribute>(propertyNameTitle, xPathTitle);
                return result;
            }
        }
        
        public string Version
        {
            get
            {
                string result = string.Empty;
                // first, try to get the version string from the assembly.
                System.Version version = Assembly.GetExecutingAssembly().GetName().Version;
                if (version != null)
                {
                    result = version.ToString();
                }

                return result;
            }
        }

        
        public string Description
        {
            get { return GetText(); }
        }

        
        public string Product
        {
            get { return CalculatePropertyValue<AssemblyProductAttribute>(propertyNameProduct, xPathProduct); }
        }

       
        public string Copyright
        {
            get { return CalculatePropertyValue<AssemblyCopyrightAttribute>(propertyNameCopyright, xPathCopyright); }
        }

        
        public string Company
        {
            get { return CalculatePropertyValue<AssemblyCompanyAttribute>(propertyNameCompany, xPathCompany); }
        }

        #endregion

        #region Commands

        public RelayCommand Back
        {
            get;
            private set;
        }

        private void OnOk()
        {
            Navigator n = new Navigator();
            n.Result = NavigateResult.None;
            n.To = NavigateTo.Main;
            Messenger.Default.Send(n);
        }

        public RelayCommand Kaloma
        {
            get;
            private set;
        }

        public RelayCommand GNU
        {
            get;
            private set;
        }

        #endregion
    }
}